using System;
using System.Collections.Generic;
using System.Text;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.ComponentModel;
using System.Web;
using System.Drawing.Design;
using System.Web.UI.Design;
using System.Collections;
using System.Security.Permissions;

namespace SharpPieces.Web.Controls
{
    [AspNetHostingPermission(SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal), AspNetHostingPermission(SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
    [DefaultEvent("FileReceived")]
    public class Upload : SharpControl
    {
        #region Private Fields

        private LinkButton _browseButton;
        private LinkButton _clearButton;
        private LinkButton _uploadButton;
        private Panel _statusPanel;
        private FileUpload _uploadControl;
        private Label _overallProgressLabel;
        private Label _fileProgressLabel;
        private Label _uploadSpeedLabel;
        private Image _overallProgressImage;
        private Image _fileProgressImage;
        private HtmlGenericControl _list;        
        private int _limitSize;
        private int _limitFiles;
        private bool _instantStart;
        private bool _allowDuplicates;
        private bool _multiple;
        private bool _enableEmbeddedSkin;
        private bool _enableEmbeddedScripts;
        private string _browseTrigger;
        private string _uploadTrigger;
        private string _clearListTrigger;
        private string _typeFilter;
        private string _onBrowse;
        private string _onSelect;
        private string _onAllSelect;
        private string _onCancel;
        private string _onBeforeOpen;
        private string _onOpen;
        private string _onProgress;
        private string _onComplete;
        private string _onError;
        private string _onAllComplete;
        private string _customPath;

        #endregion
        #region Public Delegates

        public delegate void FileReceivedEventHandler(object sender, UploadEventArgs e);

        #endregion
        #region Events

        /// <summary>
        /// Fires when a file has been successfully uploaded to the server.
        /// </summary>
        [Category("Action"), Description("Fires when a file has been successfully uploaded to the server.")]
        public event FileReceivedEventHandler FileReceived;

        #endregion
        #region Constructors

        /// <summary>
        /// Initializes a new instance of the <see cref="FileUploadExtender"/> class.
        /// </summary>
        public Upload()
        {
            _multiple = true;
            _instantStart = true;
            _allowDuplicates = false;
            _typeFilter = "{'All files (*.*)': '*.*'}";

            _uploadControl = new FileUpload();
            _uploadControl.ID = "fileUpload";
            _uploadControl.Style[HtmlTextWriterStyle.Display] = "none";

            _browseButton = new LinkButton();
            _browseButton.ID = "browseButton";
            _browseButton.Text = "Browse";
            _browseButton.CssClass = "browse";

            _clearButton = new LinkButton();
            _clearButton.ID = "clearButton";
            _clearButton.Text = "Clear";
            _clearButton.CssClass = "clear";

            _uploadButton = new LinkButton();
            _uploadButton.ID = "uploadButton";
            _uploadButton.Text = "Upload";
            _uploadButton.CssClass = "upload";

            _statusPanel = new Panel();
            _statusPanel.ID = "statusPanel";
            _statusPanel.CssClass = "status";
            _overallProgressLabel = new Label();
            _overallProgressLabel.ID = "overallProgressLabel";
            _overallProgressLabel.Text = "Overall Progress";
            _overallProgressLabel.CssClass = "overall-title";
            _fileProgressLabel = new Label();
            _fileProgressLabel.ID = "fileProgressLabel";
            _fileProgressLabel.Text = "File Progress";
            _fileProgressLabel.CssClass = "current-title";

            _overallProgressImage = new Image();
            _overallProgressImage.CssClass = "progress overall-progress";

            _fileProgressImage = new Image();
            _fileProgressImage.CssClass = "progress current-progress";

            _uploadSpeedLabel = new Label();
            _uploadSpeedLabel.CssClass = "current-text";

            _list = new HtmlGenericControl("ul");
            _list.ID = "list";
            _list.Attributes["class"] = "list";

            this.Init += new EventHandler(Upload_Init);
            this.Load += new EventHandler(Upload_Load);
            this.PreRender += new EventHandler(Upload_PreRender);

            this.CssClass = "fancyUpload";
            _enableEmbeddedSkin = true;
            _enableEmbeddedScripts = true;
        }

        #endregion
        #region Event Handlers

        /// <summary>
        /// Handles the Init event of the Upload control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        void Upload_Init(object sender, EventArgs e)
        {
            this.Controls.Add(this._uploadControl);
            this.Controls.Add(_statusPanel);

            _statusPanel.Controls.Add(_browseButton);
            _statusPanel.Controls.Add(_clearButton);
            _statusPanel.Controls.Add(_uploadButton);

            _statusPanel.Controls.Add(new LiteralControl(@"<div>"));            
            _statusPanel.Controls.Add(_overallProgressLabel);
            _statusPanel.Controls.Add(new LiteralControl(@"<br />"));
            _statusPanel.Controls.Add(_overallProgressImage);
            _statusPanel.Controls.Add(new LiteralControl(@"</div><div>"));			                
            _statusPanel.Controls.Add(_fileProgressLabel);
            _statusPanel.Controls.Add(new LiteralControl(@"<br />"));
            _statusPanel.Controls.Add(_fileProgressImage);
            _statusPanel.Controls.Add(new LiteralControl(@"</div>"));
            _statusPanel.Controls.Add(_uploadSpeedLabel);
            _statusPanel.Controls.Add(_list);
        }

        /// <summary>
        /// Handles the Load event of the Upload control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        void Upload_Load(object sender, EventArgs e)
        {
            if (!this.Page.IsPostBack)
            {
                HttpPostedFile file = this.Page.Request.Files[this._uploadControl.UniqueID];
                if (file != null && !string.IsNullOrEmpty(file.FileName))
                {
                    UploadEventArgs eventArgs = new UploadEventArgs(file);

                    OnFileReceived(eventArgs);

                    this.Page.Response.ClearContent();
                    this.Page.Response.ClearHeaders();
                    this.Page.Response.ContentType = "application/json";
                    this.Page.Response.Write(GetJSONResponse(eventArgs));
                    this.Page.Response.Flush();
                    this.Page.Response.End();
                }
            }

            if (_enableEmbeddedSkin)
            {
                this.Page.Header.Controls.Add(new LiteralControl(string.Format("<link href='{0}' rel='stylesheet' type='text/css' />", GetResourceUrl("Upload.css"))));
                _overallProgressImage.ImageUrl = GetResourceUrl("bar.gif");
                _fileProgressImage.ImageUrl = GetResourceUrl("bar.gif");
            }
        }

        /// <summary>
        /// Handles the PreRender event of the Upload control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        void Upload_PreRender(object sender, EventArgs e)
        {
            if (_enableEmbeddedScripts)
            {
                RegisterClientScriptInclude(GetResourceUrl("mootools-1.2-core-nc.js"));
                RegisterClientScriptInclude(GetResourceUrl("Swiff.Uploader.js"));
                RegisterClientScriptInclude(GetResourceUrl("Fx.ProgressBar.js"));
                RegisterClientScriptInclude(GetResourceUrl("FancyUpload2.js"));
            }

            StringBuilder script = new StringBuilder();

            script.Append("window.addEvent('load', function() {\n");
            script.AppendFormat("\tvar {0} = new FancyUpload2($('{1}'), $('{2}'), {{\n", this.UniqueID, _statusPanel.ClientID, _list.ClientID);
            script.AppendFormat("\t\turl: '{0}',\n", this.Page.Request.CurrentExecutionFilePath);
            script.AppendFormat("\t\tfieldName: '{0}',\n", this._uploadControl.UniqueID);
            
#if DEBUG
            script.Append("\t\tdebug: true,\n");
#endif            

            script.AppendFormat("\t\ttarget: '{0}',\n", BrowseControl.ClientID);
            script.AppendFormat("\t\tmultiple: {0},\n", _multiple.ToString().ToLower());

            if(!string.IsNullOrEmpty(_customPath))
                script.AppendFormat("path: '{0}', ", _customPath);

            if (_limitSize > 0)
            {
                script.AppendFormat("\t\tlimitSize: {0},\n", (_limitSize * 1024));
            }

            if (_limitFiles > 0)
            {
                script.AppendFormat("\t\tlimitFiles: {0},\n", _limitFiles);
            }

            if (_allowDuplicates)
            {
                script.AppendFormat("\t\tallowDuplicates: {0},\n", _allowDuplicates.ToString().ToLower());
            }

            if (!string.IsNullOrEmpty(_onBrowse))
            {
                script.AppendFormat("\t\tonBrowse: {0},\n", _onBrowse);
            }

            if (!string.IsNullOrEmpty(_onSelect))
            {
                script.AppendFormat("\t\tonSelect: {0},\n", _onSelect);
            }

            if (!string.IsNullOrEmpty(_onAllSelect))
            {
                script.AppendFormat("\t\tonAllSelect: {0},\n", _onAllSelect);
            }

            if (!string.IsNullOrEmpty(_onCancel))
            {
                script.AppendFormat("\t\tonCancel: {0},\n", _onCancel);
            }

            if (!string.IsNullOrEmpty(_onBeforeOpen))
            {
                script.AppendFormat("\t\tonBeforeOpen: {0},\n", _onBeforeOpen);
            }

            if (!string.IsNullOrEmpty(_onOpen))
            {
                script.AppendFormat("\t\tonOpen: {0},\n", _onOpen);
            }

            if (!string.IsNullOrEmpty(_onProgress))
            {
                script.AppendFormat("\t\tonProgress: {0},\n", _onProgress);
            }

            if (!string.IsNullOrEmpty(_onComplete))
            {
                script.AppendFormat("\t\tonComplete: {0},\n", _onComplete);
            }

            if (!string.IsNullOrEmpty(_onError))
            {
                script.AppendFormat("\t\tonError: {0},\n", _onError);
            }

            if (!string.IsNullOrEmpty(_onAllComplete))
            {
                script.AppendFormat("\t\tonAllComplete: {0},\n", _onAllComplete);
            }

            if (!string.IsNullOrEmpty(_typeFilter))
            {
                script.AppendFormat("\t\ttypeFilter: {0},", _typeFilter);
            }

            script.Remove(script.Length - 1, 1);
            script.Append("\n\t});");

            script.AppendFormat("\n\t$('{0}').addEvent('click', function() {{ {1}.browse(); return false; }});", BrowseControl.ClientID, this.UniqueID);
            script.AppendFormat("\n\t$('{0}').addEvent('click', function() {{ {1}.upload(); return false; }});", UploadControl.ClientID, this.UniqueID);
            script.AppendFormat("\n\t$('{0}').addEvent('click', function() {{ {1}.removeFile(); return false; }});", ClearControl.ClientID, this.UniqueID);

            script.Append("\n});\n");

            Page.ClientScript.RegisterStartupScript(GetType(), UniqueID, script.ToString(), true);
        }

        /// <summary>
        /// Raises the <see cref="E:FileReceived"/> event.
        /// </summary>
        /// <param name="e">The <see cref="FancyUpload.FancyUploadEventArgs"/> instance containing the event data.</param>
        protected virtual void OnFileReceived(UploadEventArgs e)
        {
            if (FileReceived != null)
            {
                FileReceived(this, e);
            }
        }

        #endregion
        #region Helpers

        /// <summary>
        /// Returns the appropriate response in JSON format, based on the current <see cref="SharpPieces.Web.Controls.UploadEventArgs"/> instance.
        /// </summary>
        /// <param name="e">The <see cref="SharpPieces.Web.Controls.UploadEventArgs"/> instance containing the event data.</param>
        /// <returns></returns>
        private string GetJSONResponse(UploadEventArgs e)
        {
            switch (e.UploadResult)
            {
                case UploadResult.Success:
                    return string.Format("{{\"result\": \"success\", \"size\": \"{0}\"}}", e.Message);
                case UploadResult.Error:
                    return string.Format("{{\"result\": \"error\", \"error\": \"{0}\"}}", e.Message);
            }

            return "{\"result\": \"success\"}";
        }

        /// <summary>
        /// Gets the resource URL.
        /// </summary>
        /// <param name="fileName">Name of the file.</param>
        /// <returns></returns>
        public string GetResourceUrl(string fileName)
        {
            return Page.ClientScript.GetWebResourceUrl(typeof(SharpPieces.Web.Controls.Upload), "SharpPieces.Web.Controls.Resources.Upload." + fileName);
        }

        /// <summary>
        /// Registers the client script include.
        /// </summary>
        /// <param name="src">The file name.</param>
        void RegisterClientScriptInclude(string src)
        {
            HtmlGenericControl si = new HtmlGenericControl();
            si.TagName = "script";
            si.Attributes.Add("type", "text/javascript");
            si.Attributes.Add("src", src);
            this.Page.Header.Controls.Add(si);
            this.Page.Header.Controls.Add(new LiteralControl("\n"));
        }

        /// <summary>
        /// Renders the control at design time.
        /// </summary>
        /// <param name="writer">The html writer.</param>
        protected override void RenderDesignTime(HtmlTextWriter writer)
        {
            writer.Write(string.Format("<input type=\"file\" size=\"30\">"));
        }

        /// <summary>
        /// Gets a reference to the control used for browsing.
        /// </summary>
        /// <value>The browse control.</value>
        internal Control BrowseControl
        {
            get
            {
                if (!string.IsNullOrEmpty(_browseTrigger))
                {
                    Control browseTrigger = this.Parent.FindControl(_browseTrigger);
                    if (browseTrigger != null)
                    {
                        return browseTrigger;
                    }
                }

                return _browseButton;
            }
        }

        /// <summary>
        /// Gets a reference to the control used for clearing the selected file list.
        /// </summary>
        /// <value>The clear control.</value>
        internal Control ClearControl
        {
            get
            {
                if (!string.IsNullOrEmpty(_clearListTrigger))
                {
                    Control clearTrigger = this.Parent.FindControl(_clearListTrigger);
                    if (clearTrigger != null)
                    {
                        return clearTrigger;
                    }
                }

                return _clearButton;
            }
        }

        /// <summary>
        /// Gets a reference to the control used for triggering the upload.
        /// </summary>
        /// <value>The upload control.</value>
        internal Control UploadControl
        {
            get
            {
                if (!string.IsNullOrEmpty(_uploadTrigger))
                {
                    Control uploadTrigger = this.Parent.FindControl(_uploadTrigger);
                    if (uploadTrigger != null)
                    {
                        return uploadTrigger;
                    }
                }

                return _uploadButton;
            }
        }

        #endregion
        #region Properties

        /// <summary>
        /// Gets or sets a value indicating whether the control will register its own script files.
        /// </summary>
        /// <value>
        /// 	<c>true</c> if the control will register its own script files; otherwise, <c>false</c>.
        /// </value>
        [Category("Behavior"),
        DefaultValue(true),
        Description("Determines wether the control will register its own script files.")]
        public bool EnableEmbeddedScripts
        {
            get { return _enableEmbeddedScripts; }
            set { _enableEmbeddedScripts = value; }
        }

        /// <summary>
        /// Gets or sets a value indicating whether the control will register its own stylesheet file.
        /// </summary>
        /// <value><c>true</c> if the control will register its own stylesheet file; otherwise, <c>false</c>.</value>
        [Category("Behavior"),
        DefaultValue(true),
        Description("Determines wether the control will register its own stylesheet file.")]
        public bool EnableEmbeddedSkin
        {
            get { return _enableEmbeddedSkin; }
            set { _enableEmbeddedSkin = value; }
        }

        /// <summary>
        /// Gets or sets the file progress text.
        /// </summary>
        /// <value>The file progress text.</value>
        [Category("Appearance"),
        DefaultValue("File Progress"),
        Description("File Progress text.")]
        public string FileProgressText
        {
            get { return _fileProgressLabel.Text; }
            set { _fileProgressLabel.Text = value; }
        }

        /// <summary>
        /// Gets or sets the overall progress text.
        /// </summary>
        /// <value>The overall progress text.</value>
        [Category("Appearance"),
        DefaultValue("Overall Progress"),
        Description("Overall Progress text.")]
        public string OverallProgressText
        {
            get { return _overallProgressLabel.Text;  }
            set { _overallProgressLabel.Text = value; }
        }

        /// <summary>
        /// Gets or sets the browse text.
        /// </summary>
        /// <value>The browse text.</value>
        [Category("Appearance"),
        DefaultValue("Browse"),
        Description("Browse text.")]
        public string BrowseText
        {
            get { return _browseButton.Text; }
            set { _browseButton.Text = value; }
        }

        /// <summary>
        /// Gets or sets the clear text.
        /// </summary>
        /// <value>The clear text.</value>
        [Category("Appearance"),
        DefaultValue("Clear"),
        Description("Clear text.")]
        public string ClearText
        {
            get { return _clearButton.Text; }
            set { _clearButton.Text = value; }
        }

        /// <summary>
        /// Gets or sets the upload text.
        /// </summary>
        /// <value>The upload text.</value>
        [Category("Appearance"),
        DefaultValue("Upload"),
        Description("Upload text.")]
        public string UploadText
        {
            get { return _uploadButton.Text; }
            set { _uploadButton.Text = value; }
        }

        /// <summary>
        /// Gets or sets the control which triggers the file browser.
        /// </summary>
        /// <value>The trigger.</value>
        [DefaultValue(""),
        IDReferenceProperty,
        TypeConverter(typeof(UploadTriggerControlConverter)),
        Themeable(false),
        Category("Behavior"),
        Description("The control which triggers the file browser.")]
        public string BrowseTrigger
        {
            get { return _browseTrigger; }
            set { _browseTrigger = value; _browseButton.Visible = false; }
        }

        /// <summary>
        /// Gets or sets the control which triggers the upload.
        /// </summary>
        /// <value>The upload trigger.</value>
        [DefaultValue(""),
        IDReferenceProperty,
        TypeConverter(typeof(UploadTriggerControlConverter)),
        Themeable(false),
        Category("Behavior"),
        Description("The control which triggers the upload. InstantStart will be ignored if this property is set.")]
        public string UploadTrigger
        {
            get { return _uploadTrigger; }
            set { _uploadTrigger = value; _uploadButton.Visible = false; }
        }

        /// <summary>
        /// Gets or sets the clear list trigger control id.
        /// </summary>
        /// <value>The clear list trigger.</value>
        [DefaultValue(""),
        IDReferenceProperty,
        TypeConverter(typeof(UploadTriggerControlConverter)),
        Themeable(false),
        Category("Behavior"),
        Description("The control which clears the upload queue.")]
        public string ClearListTrigger
        {
            get { return _clearListTrigger; }
            set { _clearListTrigger = value; _clearButton.Visible = false; }
        }

        /// <summary>
        /// Gets or sets a value indicating whether multiple selection is enabled or not.
        /// </summary>
        /// <value>
        /// 	<c>true</c> if multiple selection is enabled; otherwise, <c>false</c>.
        /// </value>
        [Category("Behavior"),
        DefaultValue(true),
        Description("Allow multiple files to be selected with the file browser.")]
        public bool EnableMultipleSelection
        {
            get { return _multiple; }
            set { _multiple = value; }
        }

        /// <summary>
        /// Gets or sets a value indicating whether the upload will be triggered automatically after the files have been chosen.
        /// </summary>
        /// <value><c>true</c> if instanrt start is enabled; otherwise, <c>false</c>.</value>
        [Category("Behavior"),
        DefaultValue(true),
        Description("Enables the upload to be triggered automatically after the files have been selected.")]
        public bool InstantStart
        {
            get { return _instantStart; }
            set { _instantStart = value; }
        }

        /// <summary>
        /// Gets or sets the number of files allowed.
        /// </summary>
        /// <value>The number of files allowed.</value>
        [Category("Behavior"),
        DefaultValue(0),
        Description("Limits the maximum number of files allowed to be uploaded. Set to 0 for unlimited.")]
        public int LimitFiles
        {
            get { return _limitFiles; }
            set { _limitFiles = value; }
        }

        /// <summary>
        /// Gets or sets the maximum file size allowed for upload, in bytes.
        /// </summary>
        /// <value>The maximum file size allowed for upload, in bytes.</value>
        [Category("Behavior"),
        DefaultValue(0),
        Description("Limits the maximum file size in bytes allowed to be uploaded. Set to 0 for unlimited.")]
        public int MaximumFileSize
        {
            get { return _limitSize; }
            set { _limitSize = value; }
        }

        /// <summary>
        /// Gets or sets a value indicating whether duplicate file names are allowed in the queue.
        /// </summary>
        /// <value><c>true</c> if duplicate file names are allowed in the queue; otherwise, <c>false</c>.</value>
        [Category("Behavior"),
        DefaultValue(false),
        Description("Enables the option of having files with the same name in the queue.")]
        public bool AllowDuplicates
        {
            get { return _allowDuplicates; }
            set { _allowDuplicates = value; }
        }

        /// <summary>
        /// Gets or sets the client action to be executed on complete.
        /// </summary>
        /// <value>The client action to be executed on complete.</value>
        [Category("Client Methods"),
        DefaultValue(""),
        Description("The client method to be called when a file upload is complete.")]
        public string OnComplete
        {
            get { return _onComplete; }
            set { _onComplete = value; }
        }

        /// <summary>
        /// Gets or sets the client action to be executed on error.
        /// </summary>
        /// <value>The on error.</value>
        [Category("Client Methods"),
        DefaultValue(""),
        Description("The client method to be called when a file upload error occured.")]
        public string OnError
        {
            get { return _onError; }
            set { _onError = value; }
        }

        /// <summary>
        /// Gets or sets the client action to be executed on cancel.
        /// </summary>
        /// <value>The on cancel.</value>
        [Category("Client Methods"),
        DefaultValue(""),
        Description("The client method to be called when a file upload has been canceled.")]
        public string OnCancel
        {
            get { return _onCancel; }
            set { _onCancel = value; }
        }

        /// <summary>
        /// Gets or sets the on client action to be executed when all files have been uploaded.
        /// </summary>
        /// <value>The client action to be executed when all files have been uploaded.</value>
        [Category("Client Methods"),
        DefaultValue(""),
        Description("The client method to be called when all uploads have been completed.")]
        public string OnAllComplete
        {
            get { return _onAllComplete; }
            set { _onAllComplete = value; }
        }

        /// <summary>
        /// Gets or sets the on client action to be executed before the files are opened.
        /// </summary>
        /// <value>The client action to be executed before the files are opened.</value>
        [Category("Client Methods"),
        DefaultValue(""),
        Description("The client method to be called before the files are opened.")]
        public string OnBeforeOpen
        {
            get { return _onBeforeOpen; }
            set { _onBeforeOpen = value; }
        }

        /// <summary>
        /// Gets or sets the on client action to be executed after the files are opened.
        /// </summary>
        /// <value>The client action to be executed after the files are opened.</value>
        [Category("Client Methods"),
        DefaultValue(""),
        Description("The client method to be called after the files are opened.")]
        public string OnOpen
        {
            get { return _onOpen; }
            set { _onOpen = value; }
        }

        /// <summary>
        /// Gets or sets the on client action to be executed before the files are uploaded.
        /// </summary>
        /// <value>The client action to be executed before the files are uploaded.</value>
        [Category("Client Methods"),
        DefaultValue(""),
        Description("The client method to be called before the files are uploaded.")]
        public string OnProgress
        {
            get { return _onProgress; }
            set { _onProgress = value; }
        }

        /// <summary>
        /// Gets or sets the on client action to be executed when the browse control is triggered.
        /// </summary>
        /// <value>The client action to be executed when the browse control is triggered.</value>
        [Category("Client Methods"),
        DefaultValue(""),
        Description("The client action to be executed when the browse control is triggered.")]
        public string OnBrowse
        {
            get { return _onBrowse; }
            set { _onBrowse = value; }
        }

        /// <summary>
        /// Gets or sets the on client action to be executed when the a file is selected.
        /// </summary>
        /// <value>The client action to be executed when a file is selected.</value>
        [Category("Client Methods"),
        DefaultValue(""),
        Description("The client action to be executed when a file is selected.")]
        public string OnSelect
        {
            get { return _onSelect; }
            set { _onSelect = value; }
        }

        /// <summary>
        /// Gets or sets the on client action to be executed when the all the files are selected.
        /// </summary>
        /// <value>The client action to be executed when the all the files are selected.</value>
        [Category("Client Methods"),
        DefaultValue(""),
        Description("The client action to be executed when the all the files are selected.")]
        public string OnAllSelect
        {
            get { return _onAllSelect; }
            set { _onAllSelect = value; }
        }

        /// <summary>
        /// Gets or sets the types.
        /// </summary>
        /// <value>The types.</value>
        [Category("Behavior"),
        DefaultValue("{'All files (*.*)': '*.*'}"),
        Description("Filter used to limit the allowed file extensions.")]
        public string TypeFilter
        {
            get { return _typeFilter; }
            set { _typeFilter = value; }
        }

        /// <summary>
        /// Get or set the custom SWF path.
        /// </summary>
        public string CustomSWFPath
        {
            get { return _customPath; }
            set { _customPath = value; }
        }

        #region Design

        /// <summary>
        /// Gets or sets the overall progress image URL.
        /// </summary>
        /// <value>The overall progress image URL.</value>
        [EditorAttribute(typeof(ImageUrlEditor), typeof(UITypeEditor)), Category("Appearance")]
        public string OverallProgressImageUrl
        {
            get { return _overallProgressImage.ImageUrl; }
            set 
            {
                if (_enableEmbeddedSkin)
                {
                    throw new NotSupportedException("The embedded skin must be disabled in order for this property to be set.");
                }
                _overallProgressImage.ImageUrl = value; 
            }
        }

        /// <summary>
        /// Gets or sets the file progress image URL.
        /// </summary>
        /// <value>The file progress image URL.</value>
        [EditorAttribute(typeof(ImageUrlEditor), typeof(UITypeEditor)), Category("Appearance")]
        public string FileProgressImageUrl
        {
            get { return _fileProgressImage.ImageUrl; }
            set 
            {
                if (_enableEmbeddedSkin)
                {
                    throw new NotSupportedException("The embedded skin must be disabled in order for this property to be set.");
                }
                _fileProgressImage.ImageUrl = value; 
            }
        }

        #endregion

        #endregion
    }
}
